export default class myPromise {
  status = 'pedding' // pedding  fulfilled  rejected
  value = undefined
  reason = undefined
  resolveCallbacks = [] //pedding状态下，存储成功的回调
  rejectCallbacks = [] //失败的回调
  constructor(executor) {
    const resolve = value => {
      if (this.status === 'pedding') {
        console.log(1)
        this.status = 'fulfilled'
        this.value = value
        this.resolveCallbacks.forEach(fn => fn(this.value))
      }
    }
    const reject = reason => {
      if ((this.status = 'pedding')) {
        this.status = 'rejected'
        this.reason = reason
        this.rejectCallbacks.forEach(fn => fn(this.reason))
      }
    }
    try {
      executor(resolve, reject)
    } catch (err) {
      reject(err)
    }
  }
  then(fn1, fn2) {
    fn1 = typeof fn1 === 'function' ? fn1 : v => v
    fn2 = typeof fn2 === 'function' ? fn2 : e => e
    if (this.status === 'pedding') {
      return new myPromise((resolve, reject) => {
        this.resolveCallbacks.push(() => {
          try {
            const newVal = fn1(this.value)
            resolve(newVal)
          } catch (err) {
            reject(err)
          }
        })
        this.rejectCallbacks.push(() => {
          try {
            const newReason = fn2(this.reason)
            reject(newReason)
          } catch (err) {
            reject(err)
          }
        })
      })
    }
    if (this.status === 'fulfilled') {
      return new myPromise((resolve, reject) => {
        try {
          const newVal = fn1(this.value)
          resolve(newVal)
        } catch (err) {
          reject(err)
        }
      })
    }
    if (this.status === 'rejected') {
      return new myPromise((resolve, reject) => {
        try {
          const newReason = fn2(this.reason)
          reject(newReason)
        } catch (err) {
          reject(err)
        }
      })
    }
  }
  catch(fn) {
    return this.then(null, fn)
  }
}

myPromise.resolve = function (value) {
  return new myPromise((resolve, reject) => {
    resolve(value)
  })
}

myPromise.reject = function (reason) {
  return new myPromise((resolve, reject) => {
    reject(reason)
  })
}

myPromise.all = function (promiseList = []) {
  return new Promise((resolve, reject) => {
    const result = [] //存储 promiseList 所有结果
    const length = promiseList.length
    let resolvedCount = 0
    promiseList.forEach(p => {
      p.then(res => {
        result.push(res)
        resolvedCount++
        if (resolvedCount === length) {
          resolve(result)
        }
      }).catch(err => {
        reject(err)
      })
    })
  })
}

myPromise.rece = function (promiseList = []) {
  return new Promise((resolve, reject) => {
    let resolved = false
    promiseList.forEach(p => {
      p.then(res => {
        if (!resolved) {
          resolve(res)
          resolved = true
        }
      }).catch(err => {
        reject(err)
      })
    })
  })
}
